unit ExeUtil;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

  type
        TExeUtil=Class(TObject)
  private
  {   Private   declarations   }
  public
  {   Public   declarations   }
   function RunProgram(aExecutablePath, aArguments: string): string;
  end;

implementation


function AnsiToWide(var aAString: AnsiString): string;

var

  temp: string;

  count: Integer;

begin

  count := Length(aAString);

  SetLength(temp, count);

  MultiByteToWideChar(CP_ACP, 0, PAnsiChar(aAString), count, PChar(temp), count);

  Result := temp;

end;

function TExeUtil.RunProgram(aExecutablePath, aArguments: string): string;

var

  buffer: array[0..4095] of AnsiChar;

  bufferStr: AnsiString;

  sa: TSecurityAttributes;

  hReadPipe, hWritePipe: THandle;

  si: TStartupInfo;

  pi: TProcessInformation;

  dwExitCode: DWORD;

  dwSize, dwRead, dwTemp: DWORD;

begin

  FillChar(sa, SizeOf(sa), 0);

  sa.nLength := SizeOf(sa);

  sa.lpSecurityDescriptor := nil;

  sa.bInheritHandle := True;

  if CreatePipe(hReadPipe, hWritePipe, @sa, SizeOf(sa)) then

  begin

    FillChar(si, SizeOf(si), 0);

    si.cb := SizeOf(si);

    si.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

    si.wShowWindow := SW_HIDE;

    si.hStdInput := hReadPipe;

    si.hStdOutput := hWritePipe;

    si.hStdError := hWritePipe;

    if (Length(aArguments) > 0) and (aArguments[1] <> ' ') then

    begin

      aArguments := ' ' + aArguments;

    end;

    if CreateProcess(PChar(aExecutablePath), PChar(aArguments), nil, nil, True, 0, nil, nil, si, pi) then

    begin

      while True do

      begin

        if GetExitCodeProcess(pi.hProcess, dwExitCode) then

        begin

          if dwExitCode <> STILL_ACTIVE then Break;

          if PeekNamedPipe(hReadPipe, nil, 0, nil, @dwSize, nil) then

          begin

            dwTemp := 0;

            while dwTemp < dwSize do

            begin

              FillChar(buffer, dwSize + 2, 0);

              if ReadFile(hReadPipe, buffer, dwSize, dwRead, nil) then

              begin

                Inc(dwTemp, dwRead);

                bufferStr := buffer;

                Result := Result + AnsiToWide(bufferStr);

              end

              else

                Break;

            end;

          end

          else

            Break;

          Sleep(10);

        end

        else

          Break;

      end;

      CloseHandle(pi.hThread);

      CloseHandle(pi.hProcess);

    end;

    CloseHandle(hReadPipe);

    CloseHandle(hWritePipe);

  end;

end;
{ TExeUtil }



end.
